Skip to content

Conversation

philnik777
Copy link
Contributor

No description provided.

@philnik777 philnik777 requested a review from a team as a code owner August 7, 2025 08:32
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Aug 7, 2025
@llvmbot
Copy link
Member

llvmbot commented Aug 7, 2025

@llvm/pr-subscribers-libcxx

Author: Nikolas Klauser (philnik777)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/152453.diff

1 Files Affected:

  • (modified) libcxx/include/__tree (+26)
diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index 3dd5ae585e1db..80ad56e5e7805 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -49,6 +49,27 @@
 _LIBCPP_PUSH_MACROS
 #include <__undef_macros>
 
+// __tree is a red-black-tree implementation used for the associative containers (i.e. (multi)map/set). To allow for
+// constant time lookup, it stores
+// - (1) a pointer to the node with the smallest (i.e. leftmost) element, namely __begin_node_
+// - (2) the number of nodes in the tree, namely __size_
+//
+// A pointer to the root of the tree is stored in the __end_node_.
+// A tree looks like this in memory:
+//
+//      __end_node_
+//           |
+//          root
+//         /    \
+//       l1       r1
+//      /  \     /  \
+//    ...  ... ...  ...
+//
+// All nodes except __end_node_ have a __left_ and __right_ pointer as well as a __parent_ pointer.
+// __end_node_ only contains a __left_ pointer, which point to the root of the tree.
+// This layout allows for iteration through the tree without a need for special handling of the end node. See
+// __tree_next_iter and __tree_prev_iter for more details.
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp, class _Compare, class _Allocator>
@@ -183,6 +204,11 @@ _LIBCPP_HIDE_FROM_ABI _NodePtr __tree_next(_NodePtr __x) _NOEXCEPT {
   return __x->__parent_unsafe();
 }
 
+// __tree_next_iter and __tree_prev_iter implement iteration through the tree. The order is as follows:
+// left sub-tree -> node -> right sub-tree. When the right-most node of a sub-tree is reached, we walk up the tree until
+// we find a node where we were in the left sub-tree. We are _always_ in a left sub-tree, since the __end_node_ points
+// to the actual root of the tree through a __left_ pointer. incrementing the end() pointer is UB, so we can assume that
+// never happens.
 template <class _EndNodePtr, class _NodePtr>
 inline _LIBCPP_HIDE_FROM_ABI _EndNodePtr __tree_next_iter(_NodePtr __x) _NOEXCEPT {
   _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");

Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the documentation, LGTM with minor tweaks!

@philnik777 philnik777 force-pushed the tree_document_layout branch from 10ed466 to e197f6f Compare August 12, 2025 07:46
@philnik777 philnik777 force-pushed the tree_document_layout branch from e197f6f to 67259fd Compare August 13, 2025 08:25
@ldionne ldionne changed the title [libc++] Document how __tree is layed out and how we iterate through it [libc++] Document how __tree is laid out and how we iterate through it Aug 13, 2025
@philnik777 philnik777 merged commit 5b25888 into llvm:main Aug 14, 2025
70 of 75 checks passed
@philnik777 philnik777 deleted the tree_document_layout branch August 14, 2025 07:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants